/** <a href="http://www.cpupk.com/decompiler">Eclipse Class Decompiler</a> plugin, Copyright (c) 2017 Chen Chao. **/
package com.minierp.service.impl;

import com.minierp.bean.AlloBillBean;
import com.minierp.bean.AlloBillItemBean;
import com.minierp.bean.UserBean;
import com.minierp.dao.AlloBillDao;
import com.minierp.dao.AlloBillItemDao;
import com.minierp.dao.IdGenerator;
import com.minierp.dao.SerialNumberDao;
import com.minierp.dao.StockBalanceDao;
import com.minierp.dao.StockDao;
import com.minierp.err.DataChangedException;
import com.minierp.err.NotAllowException;
import com.minierp.err.StockNoEnoughException;
import com.minierp.helper.PageHelper;
import com.minierp.model.AlloBill;
import com.minierp.model.AlloBillItem;
import com.minierp.model.InOutHistory;
import com.minierp.model.Product;
import com.minierp.model.Stock;
import com.minierp.model.Storehouse;
import com.minierp.model.SystemLog;
import com.minierp.service.AlloBillService;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;

public class AlloBillServiceImpl implements AlloBillService {
	public void txInsert(AlloBillBean form, AlloBillDao alloBillDao,
			AlloBillItemDao alloBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, SerialNumberDao serialNumberDao,
			IdGenerator idGenerator) throws Exception {
		AlloBill obj = form.getAlloBill();
		obj.setId(idGenerator.getId(AlloBill.class.getName()));
		if (!form.getCodeRule().getGenerateRule().equals("MANUAL")) {
			obj.setBillCode(PageHelper.generateCode(serialNumberDao,
					form.getCodeRule(), "", form.getAlloBill().getTallySetId()));

			for (AlloBill updateStock = alloBillDao.get(obj.getBillCode()); updateStock != null; updateStock = alloBillDao
					.get(obj.getBillCode())) {
				obj.setBillCode(PageHelper.generateCode(serialNumberDao, form
						.getCodeRule(), "", form.getAlloBill().getTallySetId()));
			}
		}

		alloBillDao.save(obj);
		boolean updateStock1 = false;
		if (obj.getExamined().equals("Y")) {
			updateStock1 = true;
		}

		this.saveItems(obj, updateStock1, form.getItems(), alloBillItemDao,
				stockDao, stockBalanceDao, idGenerator);
	}

	public void txUpdate(AlloBillBean form, AlloBillDao alloBillDao,
			AlloBillItemDao alloBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator)
			throws Exception {
		AlloBill obj = form.getAlloBill();
		Object[] sv = alloBillDao.getStatusValues(obj.getId());
		if (sv == null) {
			throw new Exception("Can\'t get status values for in bill:"
					+ obj.getId());
		} else {
			long existSycVal = ((Date) sv[0]).getTime();
			String exitEnabled = sv[1].toString();
			String existExamined = sv[2].toString();
			if (existSycVal != form.getSychronizeValue()) {
				throw new DataChangedException(
						"Allo bill has bean changed,get the new version and edit again.");
			} else if (existExamined.equals("Y")) {
				throw new NotAllowException("调拨单已经审核，不能修改！");
			} else if (exitEnabled.equals("N")) {
				throw new NotAllowException("调拨单已经作废，不能修改！");
			} else {
				obj.setUpdateTime(new Date());
				alloBillDao.update(obj);
				boolean updateStock = false;
				if (obj.getExamined().equals("Y")) {
					updateStock = true;
				}

				this.saveItems(obj, updateStock, form.getItems(),
						alloBillItemDao, stockDao, stockBalanceDao, idGenerator);
			}
		}
	}

	private void saveItems(AlloBill alloBill, boolean updateStock, List items,
			AlloBillItemDao alloBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator)
			throws Exception {
		int newNum = 0;

		for (int curItemId = 0; curItemId < items.size(); ++curItemId) {
			AlloBillItemBean bean = (AlloBillItemBean) items.get(curItemId);
			if (bean.getStatus().equals("NEW")) {
				++newNum;
			}
		}

		long arg12 = 0L;
		if (newNum > 0) {
			arg12 = idGenerator.getId(AlloBillItem.class.getName(), newNum);
		}

		for (int i = 0; i < items.size(); ++i) {
			AlloBillItemBean bean1 = (AlloBillItemBean) items.get(i);
			bean1.getAlloBillItem().setBillId(alloBill.getId());
			if (bean1.getStatus().equals("DELETE")) {
				if (bean1.getAlloBillItem().getId() != 0L) {
					alloBillItemDao.delete(bean1.getAlloBillItem().getId());
				}
			} else if (bean1.getStatus().equals("EDIT")) {
				alloBillItemDao.update(bean1.getAlloBillItem());
			} else if (bean1.getStatus().equals("NEW")) {
				bean1.getAlloBillItem().setId(arg12);
				alloBillItemDao.save(bean1.getAlloBillItem());
				++arg12;
			}
		}

		if (updateStock) {
			this.updateStock(alloBill, alloBillItemDao, stockDao,
					stockBalanceDao, idGenerator, "SAVE_EXAM", "");
		}

	}

	private void updateStock(AlloBill b, AlloBillItemDao alloBillItemDao,
			StockDao stockDao, StockBalanceDao stockBalanceDao,
			IdGenerator idGenerator, String operType, String stafName)
			throws Exception {
		String frStoOper = "";
		String toStoOper = "";
		if (!operType.equals("SAVE_EXAM") && !operType.equals("EXAM")) {
			frStoOper = "ADD";
			toStoOper = "SUB";
		} else {
			frStoOper = "SUB";
			toStoOper = "ADD";
		}

		SimpleDateFormat sf = new SimpleDateFormat("yyyy-MM-dd HH:mm");
		BigDecimal zero = new BigDecimal(0);
		List items = alloBillItemDao.getListWidthProd(b.getId());

		for (int j = 0; j < items.size(); ++j) {
			Object[] objs = (Object[]) items.get(j);
			AlloBillItem it = (AlloBillItem) objs[0];
			Product p = (Product) objs[1];
			Stock frs = stockDao.get(it.getProductId(), b.getFromStoId());
			new BigDecimal(0);
			new BigDecimal(0);
			if (frs == null) {
				if (frStoOper.equals("ADD")) {
					throw new StockNoEnoughException("没有id为"
							+ it.getProductId() + "产品在仓库" + b.getFromStoId()
							+ "的记录！");
				}

				throw new StockNoEnoughException("『" + p.getProductName()
						+ "』在调出仓库库存不足，当前库存量为0，差额为" + it.getAmount());
			}

			BigDecimal currentAmount = frs.getAmount();
			BigDecimal iohCost;
			BigDecimal iohUp;
			if (frStoOper.equals("ADD")) {
				iohCost = it.getCost();
				iohUp = it.getUnitPrice();
				frs.setAmount(frs.getAmount().add(it.getAmount()));
				frs.setCost(frs.getCost().add(iohCost));
			} else {
				iohCost = it.getAmount().multiply(frs.getUnitPrice())
						.setScale(2, 4);
				iohUp = frs.getUnitPrice().setScale(4, 4);
				it.setCost(iohCost);
				it.setUnitPrice(iohUp);
				alloBillItemDao.update(it);
				frs.setAmount(frs.getAmount().subtract(it.getAmount()));
				frs.setCost(frs.getCost().subtract(iohCost));
			}

			if (frs.getAmount().compareTo(zero) != 0) {
				frs.setUnitPrice(frs.getCost().divide(frs.getAmount(), 4, 4));
			}

			stockDao.update(frs);
			if (frs.getAmount().compareTo(zero) == -1) {
				throw new StockNoEnoughException("『" + p.getProductName()
						+ "』在调出仓库库存不足，当前库存量为" + currentAmount + "，差额为"
						+ frs.getAmount());
			}

			PageHelper.updateStockBalance(stockBalanceDao, it.getProductId(),
					it.getAmount(), b.getAlloDate(), iohCost, b.getFromStoId(),
					idGenerator, frStoOper);
			String toStoName = "";
			Storehouse toSto = (Storehouse) stockDao.get(Storehouse.class,
					b.getToStoId());
			if (toSto != null) {
				toStoName = toSto.getStoName();
			}

			if (operType.equals("UN_EXAM") || operType.equals("CANC")) {
				stockDao.updateIohLogData("ALLO_BILL", b.getId());
			}

			InOutHistory h = new InOutHistory();
			h.setBillId(b.getId());
			h.setBillCode(b.getBillCode());
			h.setBillDate(b.getAlloDate());
			h.setProId(it.getProductId());
			h.setStoId(b.getFromStoId());
			h.setBillType("ALLO_BILL");
			h.setId(idGenerator.getId(InOutHistory.class.getName()));
			h.setOperType(operType);
			h.setIoType("OUT");
			h.setRequId(b.getToStoId());
			h.setRequName(toStoName);
			h.setStorAmou(frs.getAmount());
			h.setStorCost(frs.getCost());
			h.setStorUp(frs.getUnitPrice());
			h.setUnitPrice(iohUp);
			if (operType.equals("UN_EXAM")) {
				h.setLogData("Y");
				h.setCost(zero.subtract(iohCost));
				h.setAmount(zero.subtract(it.getAmount()));
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "反审核单据");
			} else if (operType.equals("CANC")) {
				h.setLogData("Y");
				h.setCost(zero.subtract(iohCost));
				h.setAmount(zero.subtract(it.getAmount()));
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "作废单据");
			} else {
				h.setLogData("N");
				h.setCost(iohCost);
				h.setAmount(it.getAmount());
				h.setMark(it.getMark());
			}

			stockDao.save(h);
			Stock tos = stockDao.get(it.getProductId(), b.getToStoId());
			new BigDecimal(0);
			new BigDecimal(0);
			new BigDecimal(0);
			if (tos == null) {
				if (!toStoOper.equals("ADD")) {
					throw new StockNoEnoughException("没有id为"
							+ it.getProductId() + "产品在仓库" + b.getToStoId()
							+ "的记录！");
				}

				currentAmount = new BigDecimal(0);
				iohCost = it.getCost();
				iohUp = it.getUnitPrice();
				tos = new Stock();
				tos.setAmount(it.getAmount());
				tos.setCost(iohCost);
				tos.setUnitPrice(iohUp);
				tos.setId(idGenerator.getId(Stock.class.getName()));
				tos.setProductId(it.getProductId());
				tos.setStorehouseId(b.getToStoId());
				stockDao.save(tos);
			} else {
				currentAmount = tos.getAmount();
				iohCost = it.getCost();
				iohUp = it.getUnitPrice();
				if (toStoOper.equals("ADD")) {
					tos.setAmount(tos.getAmount().add(it.getAmount()));
					tos.setCost(tos.getCost().add(iohCost));
				} else {
					tos.setAmount(tos.getAmount().subtract(it.getAmount()));
					tos.setCost(tos.getCost().subtract(iohCost));
				}

				if (tos.getAmount().compareTo(zero) != 0) {
					tos.setUnitPrice(tos.getCost()
							.divide(tos.getAmount(), 4, 4));
				}

				stockDao.update(tos);
			}

			if (tos.getAmount().compareTo(new BigDecimal(0)) == -1) {
				throw new StockNoEnoughException("『" + p.getProductName()
						+ "』在调入仓库库存不足，当前库存量为" + currentAmount + "，差额为"
						+ tos.getAmount());
			}

			PageHelper.updateStockBalance(stockBalanceDao, it.getProductId(),
					it.getAmount(), b.getAlloDate(), iohCost, b.getToStoId(),
					idGenerator, toStoOper);
			String frStoName = "";
			Storehouse frSto = (Storehouse) stockDao.get(Storehouse.class,
					b.getFromStoId());
			if (frSto != null) {
				frStoName = frSto.getStoName();
			}

			h = new InOutHistory();
			h.setBillId(b.getId());
			h.setBillCode(b.getBillCode());
			h.setBillDate(b.getAlloDate());
			h.setProId(it.getProductId());
			h.setStoId(b.getToStoId());
			h.setBillType("ALLO_BILL");
			h.setId(idGenerator.getId(InOutHistory.class.getName()));
			h.setOperType(operType);
			h.setIoType("IN");
			h.setRequId(b.getFromStoId());
			h.setRequName(frStoName);
			h.setStorAmou(tos.getAmount());
			h.setStorCost(tos.getCost());
			h.setStorUp(tos.getUnitPrice());
			h.setUnitPrice(iohUp);
			if (operType.equals("UN_EXAM")) {
				h.setLogData("Y");
				h.setCost(zero.subtract(iohCost));
				h.setAmount(zero.subtract(it.getAmount()));
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "反审核单据");
			} else if (operType.equals("CANC")) {
				h.setLogData("Y");
				h.setCost(zero.subtract(iohCost));
				h.setAmount(zero.subtract(it.getAmount()));
				h.setMark(stafName + "于" + sf.format(h.getIoTime()) + "作废单据");
			} else {
				h.setLogData("N");
				h.setCost(iohCost);
				h.setAmount(it.getAmount());
				h.setMark(it.getMark());
			}

			stockDao.save(h);
		}

	}

	public void txExamine(long id, AlloBillDao alloBillDao,
			AlloBillItemDao alloBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			UserBean ub) throws Exception {
		AlloBill b = (AlloBill) alloBillDao.get(AlloBill.class, id);
		if (b != null && b.getEnabled().equals("Y")
				&& b.getExamined().equals("N")) {
			this.updateStock(b, alloBillItemDao, stockDao, stockBalanceDao,
					idGenerator, "EXAM", "");
			b.setExamined("Y");
			b.setUpdateTime(new Date());
			b.setExamineTime(new Date());
			b.setExaminerId(ub.getStaffer().getId());
			b.setExaminerName(ub.getStaffer().getStafferName());
			alloBillDao.update(b);
		}

	}

	public void txUnExamine(long id, AlloBillDao alloBillDao,
			AlloBillItemDao alloBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			UserBean ub) throws Exception {
		AlloBill b = (AlloBill) alloBillDao.get(AlloBill.class, id);
		if (b != null && b.getEnabled().equals("Y")
				&& b.getExamined().equals("Y")) {
			this.updateStock(b, alloBillItemDao, stockDao, stockBalanceDao,
					idGenerator, "UN_EXAM", ub.getStaffer().getStafferName());
			b.setExamined("N");
			b.setUpdateTime(new Date());
			b.setExaminerId(0L);
			b.setExaminerName("");
			alloBillDao.update(b);
		}

	}

	public void txCancel(long id, String reason, AlloBillDao alloBillDao,
			AlloBillItemDao alloBillItemDao, StockDao stockDao,
			StockBalanceDao stockBalanceDao, IdGenerator idGenerator,
			UserBean ub) throws Exception {
		AlloBill b = (AlloBill) alloBillDao.get(AlloBill.class, id);
		if (b != null && b.getEnabled().equals("Y")) {
			if (b.getExamined().equals("Y")) {
				this.updateStock(b, alloBillItemDao, stockDao, stockBalanceDao,
						idGenerator, "CANC", ub.getStaffer().getStafferName());
			}

			b.setEnabled("N");
			b.setDisableManId(ub.getStaffer().getId());
			b.setUpdateTime(new Date());
			alloBillDao.update(b);
			SystemLog log = new SystemLog();
			log.setId(idGenerator.getId(SystemLog.class.getName()));
			log.setActionCode("ALLO_BILL");
			log.setLogType("CANCEL_LOG");
			log.setCreaterId(ub.getStaffer().getId());
			log.setCreaterName(ub.getStaffer().getStafferName());
			log.setDepName(ub.getDepName());
			log.setDepId(ub.getStaffer().getDepartmentId());
			log.setStatus("S");
			log.setUserName(ub.getUser().getUserName());
			log.setIp(b.getBillCode());
			log.setMark("");
			log.setRelId(id);
			log.setCancelReason(reason);
			log.setTallySetId(b.getTallySetId());
			alloBillDao.save(log);
		}

	}
}